package modele;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;

import javax.sound.sampled.spi.AudioFileReader;
import javax.swing.Timer;

import java.io.File;
import java.io.IOException;
import java.io.Reader;
import java.net.URL;

import javax.imageio.ImageIO;

import memory.WavPlayer;

import java.util.Observable;

public class MCard extends Observable implements ActionListener {
	
	/*
	 * Modele d'une carte, caracterise :
	 * -son image
	 * -son etat (face visible ou caché)
	 * Permet l'accès a ces données
	 */
	
	protected static final int VIEW_TIME = 1000;
	
	protected MGrid grid;
	protected BufferedImage back, front;
	protected boolean showed, locked, visible;
	
	public MCard(MGrid gridM ,BufferedImage image) {
		grid = gridM;
		showed = true; //vrai si front (coté image) est affiché
		locked = true; //vrai si la carte n'est plus cliquable
		visible = true; //vrai si la carte doit etre affiché
		
		try {
			back = ImageIO.read(getClass().getResourceAsStream("back.png"));
			front = image;
		} catch (IOException e) {}
	}
	
	/*
	 * Getters & Setters
	 */
	
	public BufferedImage getBack() {
		return back;
	}

	public BufferedImage getFront() {
		return front;
	}

	public boolean isShowed() {
		return showed;
	}
	
	public void switchShowed() {
		showed = !showed;
	}

	public boolean isLocked() {
		return locked;
	}

	public void setLocked(boolean locked) {
		this.locked = locked;
	}

	public boolean isVisible() {
		return visible;
	}
	
	public void setVisible(boolean visible) {
		this.visible = visible;
	}
	
	/*
	 * Méthodes liées a la mise a jour des cartes lors de la phase de jeu
	 */

	@Override
	//Renvoi vrai ssi les deux cartes ont la même image front
	public boolean equals(Object obj) {
		if(obj.getClass().equals(getClass())) {
			MCard m = (MCard) obj;
			if(m.getFront().equals(getFront()))
				return true;
		}
		return false;
	}

	/*
	 * Appelée par CActionCard
	 *-Invoquée uniquement si la carte n'est pas verrouillée
	 *-Retourne la carte
	 *-La compare avec la carte precedement cliquée (si il y en a une)
	 *--Retourne ou fait disparaitre les deux cartes après un délai
	 */
	public void update() {
			//Retournement de la carte (effecté a chaque fois)
			switchShowed();
			setLocked(true);
			refresh();
			
			if(grid.hasFirstSelected()) {
				//Si la carte est "cliquée en deuxième", utilisation d'un Timer pour simuler un temps d'attente
				grid.lockAll(true);
				Timer t = new Timer(MCard.VIEW_TIME, this);
				t.setRepeats(false);
				t.start();
				/*Voir actionPerformed...*/
			}
			else {
				//Sinon, inscription auprès de la grille comme carte "cliquée en premier"
				grid.setFirstSelected(this);
			}
			
	}
	
	@Override
	public void actionPerformed(ActionEvent e) {
		
		/*
		 * Methode appelée par le timer de update()
		 * Permet de retourner/masquer les cartes jouées après un delai etabli
		 */
		
		

		if(this.equals(grid.getFirstSelected())) {
			//Affichage d'un cadre vert + refresh
			
			//d�clanche le son du succ�s
			try {
				WavPlayer player;
				player = new WavPlayer(getClass().getResource("succes.wav"));
				Thread ThPlayer = new Thread(player);
				ThPlayer.start();
			} catch (Exception e1) {}
			
			this.setVisible(false);
			grid.getFirstSelected().setVisible(false);
		}
		else {
			//Affichage d'un cadre rouge + refresh
			
			//d�clanche le son de l'echec
			try {
				WavPlayer player;
				player = new WavPlayer(getClass().getResource("fail.wav"));
				Thread ThPlayer = new Thread(player);
				ThPlayer.start();
			} catch (Exception e1) {}
			
			this.switchShowed();
			grid.getFirstSelected().switchShowed();
		}
		grid.lockAll(false);
		
		this.refresh();
		grid.getFirstSelected().refresh();
		
		grid.setFirstSelected(null);
		grid.update();
	}
	
	//Signalisation d'un changement aux observers (VCard)
	public void refresh() {
		setChanged();
		notifyObservers(null);
	}

	
}
